using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using ERF;

namespace ERF.Menu
{
    /// <summary>
    /// This class draws a simple menu in 2D.
    /// </summary>
    public class MenuManager : DrawableGameComponent
    {
        private ERFGame game;
        private SpriteFont font;
        private SpriteBatch spriteBatch;
        private Menu menu;
        private int startX = 20;
        private int startY = 200;

        public Menu Menu
        {
            get { return menu; }
            set { menu = value; }
        }

        /// <summary>
        /// Singleton instance
        /// </summary>
        private static MenuManager instance;

        /// <summary>
        /// Get an instance of this state.
        /// </summary>
        /// <param name="machine">the state machine that this state should belong to.</param>
        /// <returns></returns>
        public static MenuManager GetInstance(ERFGame game)
        {
            if (instance == null)
                instance = new MenuManager(game);

            return instance;
        }

        public MenuManager(ERFGame game) : base(game)
        {
            this.game = game;
            this.game.Components.Add(this);
            this.DrawOrder = int.MaxValue;
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(game.GraphicsDevice);
            font = game.Content.Load<SpriteFont>(@"Fonts2\\menufont");
        }

        /// <summary>
        /// Draws a simple menu and draws the selected menu item in a different color.
        /// Note: Does not work for nested menus yet.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);

            drawMenu(this.menu, startX, startY);

            spriteBatch.End();

            base.Draw(gameTime);
        }

        private void drawMenu(MenuList menu, float x, float y)
        {
            float my = 0;
            foreach (MenuItem mi in menu.MenuItems)
            {
                Vector2 pos = new Vector2(x, y + my);

                //Draw title of menu item
                if (menu.SelectedItem.Equals(mi))
                {
                    spriteBatch.DrawString(font, mi.Title, pos, Color.White);
                }
                else
                    spriteBatch.DrawString(font, mi.Title, pos, Color.Goldenrod);

                //Draw selected item in submenu
                if (mi.GetType() == typeof(MenuList) && this.menu.CurrentList.Equals(mi))
                {
                    drawMenu((MenuList)mi, x + 200, y + my);
                }
                else if (mi.GetType() == typeof(MenuList) && this.menu.CurrentList.GetType() != typeof(MenuList))
                {
                    spriteBatch.DrawString(font, ((MenuList)mi).SelectedItem.Title, pos + new Vector2(x + 200, 0), Color.WhiteSmoke);
                }

                my += font.MeasureString(mi.Title).Y;
            }
        }

        /// <summary>
        /// This Selects a menuItem in the menu by checking the current position of the mouse and where the menuItems are.
        /// Note: Does not work for nested menus yet.
        /// </summary>
        public void Select(Vector2 position)
        {
            for (int i = 0; i < menu.MenuItems.Count; i++)
            {
                Vector2 mp = font.MeasureString(menu.MenuItems[i].Title);
                if (position.X >= startX && position.Y >= startY && position.X <= mp.X && position.Y <= mp.Y)
                {
                    menu.SelectedIndex = i;
                    break;
                }
            }
            menu.Submit();
        }
    }
}